home *** CD-ROM | disk | FTP | other *** search
- CODE_SEG SEGMENT
- ORG 100H ;ORG 100H for a .com file
- ASSUME CS:CODE_SEG,DS:CODE_SEG
- FIRST: JMP ENTRY ;Skip over data area
- COPYRIGHT DB '(C) S. HOLZNER 1984'
- TARGET_FCB DB 37 DUP(0) ;FCB at 6CH will be written over
- END_FLAG DW 0 ;Flag set after everything read
- FILE_SIZE_LO DW 0 ;Low word of file size, in bytes
- FILE_SIZE_HI DW 0 ;High word of same
- FILE_SIZE_K DW 0 ;Number of Clusters to write
- DTA_OFFSET DW 0 ;Used for 1K increments into DTA
- COPY_MSG_1 DB 13,10,'Copy $' ;Part 1 of the copy prompt
- COPY_MSG_2 DB ' (Y/N)?$' ;And part 2
- FULL_MSG DB 13,10,'Disk Full$' ;Trouble message
-
- MOVE PROC NEAR ;The main (and only) procedure
- ENTRY: MOV CX,32 ;Copy over 1st 32 bytes of default DTA
- MOV SI,6CH ; from 6CH into Target_FCB area for
- LEA DI,TARGET_FCB ; later use as new file name
- REP MOVSB
- MOV DX,5CH ;The source FCB
- MOV AH,11H ;Check if there is match to source file
- INT 21H
- CMP AL,0FFH ;0FFH -> No match
- JNE QUERY ;Match
- JMP OUT ;No Match
- QUERY: MOV AH,9H ;Print out prompt message
- LEA DX,COPY_MSG_1
- INT 21H
- MOV CX,11 ;Print out 11 letters of found file name
- MOV BX,81H ;Point to match in default DTA
- MOV AH,2
- QLOOP: MOV DL,[BX] ;Get letter of found file's name
- INC BX ;Point to next letter
- INT 21H
- LOOP QLOOP ;Keep going until all 11 printed
- MOV AH,9H ;Print out 2nd half of prompt message
- LEA DX,COPY_MSG_2
- INT 21H
- MOV AH,1 ;Get a 1 character response
- INT 21H
- CMP AL,'Y' ;Was it a 'Y'?
- JE DO_COPY ;Yes, copy the file
- CMP AL,'y' ;No...perhaps a 'y'?
- JE DO_COPY ;Yes, copy the file
- JMP NEXT ;Get next match (if none, leave)
- DO_COPY:MOV CX,37 ;Using given target file as a template,
- LEA SI,TARGET_FCB ; load its 37 characters into the FCB
- MOV DI,0C0H ; for use as real target FCB, checking
- CMP BYTE PTR [SI+1],' ' ; for wildcards. First, was DRIVE: given
- JNE NLOOP ; as target? No, check wildcards.
- PUSH DI ;Yes, fill Target_FCB with wildcard ?'s
- PUSH CX ; so found filename will be used
- LEA DI,TARGET_FCB
- INC DI
- MOV CX,11 ;Put in 11 ?'s
- MOV AL,'?'
- REP STOSB ;Do the fill
- POP CX ;Restore counter and dest. pointer
- POP DI
- NLOOP: MOV BX,0 ;Move given target name into real used
- CMP BYTE PTR [SI],'?' ; target FCB at 0C0H. If a wildcard is
- JNE CHAR_OK ; found in given filename use corres-
- MOV BX,80H ; ponding character in found filename
- SUB BX,OFFSET TARGET_FCB ;Wildcard found, adjust source (SI) to
- ADD SI,BX ; point to the found filename
- CHAR_OK:MOVS [DI],[SI]
- SUB SI,BX ;Restore SI if necessary
- LOOP NLOOP ;Loop back until for all 11 name char.s
- MOV DX,80H ;Target FCB now at 0C0H, source at 80H
- MOV AH,0FH ;Use DOS service 15 to open source
- INT 21H ;Open source FCB
- MOV DX,0C0H ;Use DOS service 12 to create target
- MOV AH,16H
- INT 21H ;Create target FCB (or if the file
- AND END_FLAG,0 ; already exists, zero it and refill it)
- MOV BX,80H + 14
- MOV WORD PTR [BX],8000H ;Set record size for source (32K)
- MOV BX,80H + 16 ;Get file size from opened source FCB
- MOV AX,[BX]
- MOV FILE_SIZE_LO,AX ;Store low word of size in FILE_SIZE_LO
- ADD BX,2 ;Point to high word
- MOV DX,[BX]
- MOV FILE_SIZE_HI,DX ;Store high word of size in FILE_SIZE_HI
- MOV CX,1024 ;Div DX:AX (High:Low of size) by 1024
- DIV CX
- MOV FILE_SIZE_K,AX ;Get file size in rounded-up K (1024)
- TEST DX,0FFFFH ;Was it an even K file:Mod(size,1024)=0?
- JZ ROUND ;Yes, don't add cluster for file remnant
- INC FILE_SIZE_K ;No, add 1 more cluster for remainder
- ROUND: MOV BX,0C0H + 14
- MOV WORD PTR [BX],400H ;Set record size for target (1K)
- READ: LEA DX,DATA_POINT ;Set up the 32K DTA we'll use
- MOV AH,1AH ; at the end of this program
- INT 21H
- MOV DX,80H ;Point to source FCB to prepare for read
- MOV AH,14H
- INT 21H ;Do the read of 32K bytes
- CMP AL,0 ;AL = 0 if end of file not yet reached
- JLE READ_OK
- OR END_FLAG,1 ;Have read in the whole file, DTA is
- READ_OK:MOV CX,20H ; stuffed with zeroes after end of file
- LEA DX,DATA_POINT ;Reset our offset into 32K DTA to the
- MOV DTA_OFFSET,DX ; start
- WLOOP: MOV DX,0C0H ;Point to target FCB, prepare for write
- MOV AH,15H
- INT 21H ;Do the write 1K at a time
- CMP AL,0 ;Was the write a success?
- JE COPY_OK ;Yes, check if done writing
- LEA DX,FULL_MSG ;No, assume the disk was full and say so
- MOV AH,9H ;Print error string
- INT 21H
- JMP OUT ;Exit
- COPY_OK:DEC FILE_SIZE_K ;Decrement number of clusters to write
- JZ FINISH ;Done?
- ADD DTA_OFFSET,400H ;No, point to next 1K chunk of DTA
- MOV DX,DTA_OFFSET
- MOV AH,1AH ;Set DTA to match
- INT 21H
- LOOP WLOOP ;Repeat until 32K written or end of file
- TEST END_FLAG,1 ;Have we read in the end of file?
- JZ READ ;No, get next 32K block from source
- FINISH: MOV AX,FILE_SIZE_LO ;Now adjust written file's size
- MOV BX,0C0H + 16 ;Point to low word of size
- MOV WORD PTR [BX],AX ;And set it to the correct value
- ADD BX,2 ;Point to high word of size
- MOV AX,FILE_SIZE_HI ;And set it too
- MOV WORD PTR [BX],AX
- MOV AH,10H ;Request DOS service 16, close files
- MOV DX,0C0H ;Point to target file's FCB
- INT 21H ;Close target with correct size
- MOV DX,80H ;Point to source file's FCB
- INT 21H ;Close source
- NEXT: MOV DX,80H ;Start looking for the next match
- MOV AH,1AH ;First, reset DTA to 80H for found file's FCB
- INT 21H
- MOV AH,12H ;Now search for next match-service 18
- MOV DX,5CH ;Use given filename to match to
- INT 21H
- CMP AL,0 ;Match found?
- JNE OUT ;No, exit.
- JMP QUERY ;Yes, ask if it should be copied
- OUT: RET
-
- MOVE ENDP
- DATA_POINT: ;The 32K DTA starts here
- CODE_SEG ENDS
- END FIRST ;'END FIRST' so entry point set to FIRST
-